package org.cybzacg.encryption.examples;

import org.cybzacg.encryption.annotations.Encrypt;
import org.cybzacg.encryption.annotations.Decrypt;
import org.cybzacg.encryption.annotations.Sign;
import org.cybzacg.encryption.annotations.Verify;
import org.cybzacg.encryption.annotations.processor.AnnotationProcessor;
import org.cybzacg.encryption.context.EncryptionContext;
import org.cybzacg.encryption.context.impl.DefaultEncryptionContext;
import org.cybzacg.encryption.enums.EncryptionAlgorithm;

import java.util.ArrayList;
import java.util.List;

/**
 * 注解使用示例
 * 演示如何使用加密注解进行自动加密/解密
 * 
 * @author encryption team
 * @version 1.0
 */
public class AnnotationExample {
    
    /**
     * 用户数据类
     * 使用注解标记需要加密的字段
     */
    public static class UserData {
        
        @Encrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256)
        private String password;
        
        @Encrypt(algorithm = EncryptionAlgorithm.RSA, keySize = 2048)
        private String privateKey;
        
        @Decrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256)
        private String encryptedPassword;
        
        @Sign(algorithm = EncryptionAlgorithm.RSA, keySize = 2048, signatureAlgorithm = "SHA256withRSA")
        private byte[] signature;
        
        @Verify(algorithm = EncryptionAlgorithm.RSA, keySize = 2048, signatureAlgorithm = "SHA256withRSA")
        private boolean signatureValid;
        
        @Encrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256, cacheEnabled = true, cacheExpiration = 60000)
        private String sensitiveData;
        
        // 构造函数
        public UserData(String password, String privateKey, String sensitiveData) {
            this.password = password;
            this.privateKey = privateKey;
            this.sensitiveData = sensitiveData;
        }
        
        // Getter和Setter方法
        public String getPassword() {
            return password;
        }
        
        public void setPassword(String password) {
            this.password = password;
        }
        
        public String getPrivateKey() {
            return privateKey;
        }
        
        public void setPrivateKey(String privateKey) {
            this.privateKey = privateKey;
        }
        
        public String getEncryptedPassword() {
            return encryptedPassword;
        }
        
        public void setEncryptedPassword(String encryptedPassword) {
            this.encryptedPassword = encryptedPassword;
        }
        
        public byte[] getSignature() {
            return signature;
        }
        
        public void setSignature(byte[] signature) {
            this.signature = signature;
        }
        
        public boolean isSignatureValid() {
            return signatureValid;
        }
        
        public void setSignatureValid(boolean signatureValid) {
            this.signatureValid = signatureValid;
        }
        
        public String getSensitiveData() {
            return sensitiveData;
        }
        
        public void setSensitiveData(String sensitiveData) {
            this.sensitiveData = sensitiveData;
        }
        
        @Override
        public String toString() {
            return "UserData{" +
                    "password='[PROTECTED]'," +
                    ", privateKey='[PROTECTED]'," +
                    ", encryptedPassword='" + encryptedPassword + '\'' +
                    ", signatureLength=" + (signature != null ? signature.length : 0) +
                    ", signatureValid=" + signatureValid +
                    ", sensitiveData='[PROTECTED]'" +
                    '}';
        }
    }
    
    /**
     * 服务类
     * 演示方法级别的注解使用
     */
    public static class DataService {
        
        /**
         * 加密敏感数据
         * 
         * @param data 原始数据
         * @return 加密后的数据
         */
        @Encrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256)
        public String encryptSensitiveData(String data) {
            // 方法体会被注解处理器自动处理
            return data; // 实际返回值会被注解处理器替换为加密后的数据
        }
        
        /**
         * 解密敏感数据
         * 
         * @param encryptedData 加密数据
         * @return 原始数据
         */
        @Decrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256)
        public String decryptSensitiveData(String encryptedData) {
            // 方法体会被注解处理器自动处理
            return encryptedData; // 实际返回值会被注解处理器替换为解密后的数据
        }
        
        /**
         * 处理用户数据
         * 
         * @param userData 用户数据
         * @param sensitiveData 敏感数据
         * @return 处理结果
         */
        public String processUserData(
                UserData userData, 
                @Encrypt(algorithm = EncryptionAlgorithm.AES, keySize = 256) String sensitiveData) {
            // 参数会被注解处理器自动加密
            return "Processed: " + userData.toString() + ", sensitive: " + sensitiveData;
        }
        
        /**
         * 验证用户数据
         * 
         * @param userData 用户数据
         * @param signature 签名
         * @return 验证结果
         */
        public boolean verifyUserData(
                UserData userData, 
                @Verify(algorithm = EncryptionAlgorithm.RSA, keySize = 2048) String signature) {
            // 签名会被注解处理器自动验证
            return userData.isSignatureValid();
        }
    }
    
    /**
     * 主方法 - 演示注解处理器的使用
     */
    public static void main(String[] args) {
        System.out.println("=== 加密注解处理器使用示例 ===\n");
        
        // 创建加密上下文
        EncryptionContext context = new DefaultEncryptionContext.Builder()
                .algorithm(EncryptionAlgorithm.AES)
                .build();
        
        // 示例1：字段级别的加密/解密
        System.out.println("1. 字段级别的加密/解密示例:");
        demonstrateFieldEncryption(context);
        
        // 示例2：方法级别的加密/解密
        System.out.println("\n2. 方法级别的加密/解密示例:");
        demonstrateMethodEncryption(context);
        
        // 示例3：参数级别的加密/解密
        System.out.println("\n3. 参数级别的加密/解密示例:");
        demonstrateParameterEncryption(context);
        
        // 示例4：签名和验证
        System.out.println("\n4. 签名和验证示例:");
        demonstrateSignatureAndVerification(context);
        
        // 示例5：批量处理
        System.out.println("\n5. 批量处理示例:");
        demonstrateBatchProcessing(context);
    }
    
    /**
     * 演示字段级别的加密/解密
     */
    private static void demonstrateFieldEncryption(EncryptionContext context) {
        try {
            // 创建用户数据
            UserData userData = new UserData("mypassword123", "privatekey123", "sensitiveinfo");
            
            System.out.println("原始数据: " + userData);
            
            // 加密字段
            AnnotationProcessor.ProcessingResult encryptResult = 
                AnnotationProcessor.processEncryption(userData, context);
            System.out.println("加密结果: " + encryptResult.getMessage());
            System.out.println("加密后数据: " + userData);
            
            // 解密字段
            AnnotationProcessor.ProcessingResult decryptResult = 
                AnnotationProcessor.processDecryption(userData, context);
            System.out.println("解密结果: " + decryptResult.getMessage());
            System.out.println("解密后数据: " + userData);
            
        } catch (Exception e) {
            System.err.println("字段加密/解密失败: " + e.getMessage());
        }
    }
    
    /**
     * 演示方法级别的加密/解密
     */
    private static void demonstrateMethodEncryption(EncryptionContext context) {
        try {
            DataService dataService = new DataService();
            
            String originalData = "This is sensitive data";
            System.out.println("原始数据: " + originalData);
            
            // 加密数据
            AnnotationProcessor.ProcessingResult encryptResult = 
                AnnotationProcessor.processMethodEncryption(
                    dataService, "encryptSensitiveData", 
                    new Object[]{originalData}, 
                    context
                );
            System.out.println("方法加密结果: " + encryptResult.getMessage());
            
            // 解密数据
            AnnotationProcessor.ProcessingResult decryptResult = 
                AnnotationProcessor.processMethodDecryption(
                    dataService, "decryptSensitiveData", 
                    new Object[]{"encrypted_data"}, 
                    context
                );
            System.out.println("方法解密结果: " + decryptResult.getMessage());
            
        } catch (Exception e) {
            System.err.println("方法加密/解密失败: " + e.getMessage());
        }
    }
    
    /**
     * 演示参数级别的加密/解密
     */
    private static void demonstrateParameterEncryption(EncryptionContext context) {
        try {
            DataService dataService = new DataService();
            UserData userData = new UserData("password123", "key456", "data789");
            String sensitiveData = "very sensitive information";
            
            System.out.println("原始敏感数据: " + sensitiveData);
            
            // 处理数据（参数会被自动加密）
            AnnotationProcessor.ProcessingResult processResult = 
                AnnotationProcessor.processMethodEncryption(
                    dataService, "processUserData", 
                    new Object[]{userData, sensitiveData}, 
                    context
                );
            System.out.println("参数加密处理结果: " + processResult.getMessage());
            
        } catch (Exception e) {
            System.err.println("参数加密/解密失败: " + e.getMessage());
        }
    }
    
    /**
     * 演示签名和验证
     */
    private static void demonstrateSignatureAndVerification(EncryptionContext context) {
        try {
            UserData userData = new UserData("password123", "key456", "data789");
            
            // 模拟签名过程（实际应用中会使用私钥签名）
            userData.setSignature("mock_signature_data".getBytes());
            userData.setSignatureValid(true);
            
            System.out.println("用户数据: " + userData);
            
            // 验证签名
            AnnotationProcessor.ProcessingResult verifyResult = 
                AnnotationProcessor.processMethodEncryption(
                    new Object() {}, // 使用匿名对象作为目标
                    "verifyUserData", 
                    new Object[]{userData, "signature_data"}, 
                    context
                );
            System.out.println("签名验证结果: " + verifyResult.getMessage());
            
        } catch (Exception e) {
            System.err.println("签名验证失败: " + e.getMessage());
        }
    }
    
    /**
     * 演示批量处理
     */
    private static void demonstrateBatchProcessing(EncryptionContext context) {
        try {
            // 创建多个用户数据对象
            List<UserData> userList = new ArrayList<>();
            for (int i = 0; i < 5; i++) {
                userList.add(new UserData("password" + i, "key" + i, "data" + i));
            }
            
            System.out.println("批量处理 " + userList.size() + " 个用户对象");
            
            // 批量加密
            int successCount = 0;
            int failureCount = 0;
            
            for (UserData userData : userList) {
                AnnotationProcessor.ProcessingResult result = 
                    AnnotationProcessor.processEncryption(userData, context);
                
                if (result.isSuccess()) {
                    successCount++;
                } else {
                    failureCount++;
                    System.err.println("加密失败: " + result.getMessage());
                }
            }
            
            System.out.println("批量加密完成 - 成功: " + successCount + ", 失败: " + failureCount);
            
            // 批量解密
            successCount = 0;
            failureCount = 0;
            
            for (UserData userData : userList) {
                AnnotationProcessor.ProcessingResult result = 
                    AnnotationProcessor.processDecryption(userData, context);
                
                if (result.isSuccess()) {
                    successCount++;
                } else {
                    failureCount++;
                    System.err.println("解密失败: " + result.getMessage());
                }
            }
            
            System.out.println("批量解密完成 - 成功: " + successCount + ", 失败: " + failureCount);
            
        } catch (Exception e) {
            System.err.println("批量处理失败: " + e.getMessage());
        }
    }
    
    /**
     * 演示注解处理器的缓存功能
     */
    public static void demonstrateCacheFeatures() {
        System.out.println("\n=== 注解处理器缓存功能演示 ===");
        
        System.out.println("当前缓存大小: " + AnnotationProcessor.getCacheSize());
        
        // 清除缓存
        AnnotationProcessor.clearCache();
        System.out.println("缓存已清除，当前大小: " + AnnotationProcessor.getCacheSize());
        
        // 重新处理以填充缓存
        EncryptionContext context = new DefaultEncryptionContext.Builder()
                .algorithm(EncryptionAlgorithm.AES)
                .build();
        
        UserData userData = new UserData("test", "test", "test");
        AnnotationProcessor.processEncryption(userData, context);
        
        System.out.println("处理后缓存大小: " + AnnotationProcessor.getCacheSize());
    }
    
    /**
     * 演示错误处理
     */
    public static void demonstrateErrorHandling() {
        System.out.println("\n=== 错误处理演示 ===");
        
        try {
            // 尝试处理null对象
            AnnotationProcessor.ProcessingResult result = 
                AnnotationProcessor.processEncryption(null, null);
            System.out.println("Null对象处理: " + result.getMessage());
            
            // 尝试处理无效方法
            AnnotationProcessor.ProcessingResult result2 = 
                AnnotationProcessor.processMethodEncryption(
                    new Object(), "nonExistentMethod", 
                    new Object[]{}, 
                    null
                );
            System.out.println("无效方法处理: " + result2.getMessage());
            
        } catch (Exception e) {
            System.err.println("错误处理演示失败: " + e.getMessage());
        }
    }
}
